package csc.main;

import csc.triangulation.Vector3d;
import csc.util.Utils;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Stanislau Dubrouski
 */
public class Shift implements Comparable<Shift> {

    private Vector3d begins;
    private Vector3d ends;

    /**
     *
     * @param begins
     * @param ends
     */
    public Shift(Vector3d begins, Vector3d ends) {
        this.begins = begins;
        this.ends = ends;
    }

    /**
     *
     * @param get
     */
    public Shift(Shift get) {
        this.begins = new Vector3d(get.begins.getX(), get.begins.getY(), get.begins.getZ());
        this.ends = new Vector3d(get.ends.getX(), get.ends.getY(), get.ends.getZ());
    }

    /**
     *
     * @return 1st vector from color pair
     */
    public Vector3d getBeginVector() {
        return begins;
    }

    /**
     *
     * @param begin
     */
    public void setBeginVector(Vector3d begin) {
        this.begins = begin;
    }

    /**
     *
     * @return 2nd vector from clor pair 
     */
    public Vector3d getEndVector() {
        return ends;
    }

    /**
     *
     * @param end
     */
    public void setEndVector(Vector3d end) {
        this.ends = end;
    }

    /**
     * @param pair
     * @return vector, representing shift with 1st vector in pair set to (0,0,0)
     */
    public Vector3d computeShiftValue() {
        return new Vector3d(
                this.getEndVector().getX() - this.getBeginVector().getX(),
                this.getEndVector().getY() - this.getBeginVector().getY(),
                this.getEndVector().getZ() - this.getBeginVector().getZ());
    }

    /**
     *
     * @param o
     * @return comparation result based on x-coordinate
     */
    public int compareTo(Shift o) {
        Shift other = (Shift)o;
        return (int)(other.getBeginVector().getX() - this.begins.getX());
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 89 * hash + this.begins.hashCode();
        hash = 89 * hash + this.ends.hashCode();
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Shift other = (Shift) obj;
        if (!this.begins.equals(other.begins)) {
            return false;
        }
        if (!this.ends.equals(other.ends)) {
            return false;
        }
        return true;
    }

    /**
     *
     * @return String representation of the shift
     */
    @Override
    public String toString() {
        return "Shift: begins {" + this.begins.toString() + "}, ends {" + this.ends.toString() + "};";
    }

    /**
     *
     * @param shifts
     * @return mean shift calculated from input shifts sizes
     */
    public static float calculateMeanShift(List<Shift> shifts) {
        List<Float> vals = new ArrayList<Float>();
        for (Shift s : shifts) {
            vals.add(Vector3d.computeVectorsDistance(s.getBeginVector(), s.getEndVector()));
        }
        return Utils.computeMeanValue(vals);
    }
    
    /**
     *
     * @param shifts
     * @return standard deviation calculated from input shifts sizes
     */
    public static float calculateShiftStandardDeviation(List<Shift> shifts) {
        List<Float> vals = new ArrayList<Float>();

        for (Shift s : shifts) {
            vals.add(Vector3d.computeVectorsDistance(s.getBeginVector(), s.getEndVector()));
        }

        return Utils.computeStandartDeviation(vals);
    }
}